/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.ljmu.mulgaraifz.httprequests;

import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.log4j.Logger;
import org.igfay.jfig.JFig;
//TODO Fix the parameters from the configuration file, out of date, section not present anymore so 
// now using the default contants parameters
public class HttpCustomParameters {
	
	private static Logger log = Logger.getLogger(HttpCustomParameters.class);
	
	private static final String DEFAULT_PORT = "8080";

	private static final String DEFAULT_PROTOCOL = "http";

	private static final String DEFAULT_SSL_PORT = "443";

	private static final String DEFAULT_SSL_PROTOCOL = "https";

	/** Seconds to wait before a connection is established. */
	public int TIMEOUT_MS = 20000;

	/** Seconds to wait while waiting for data over the socket (SO_TIMEOUT). */
	public int SOCKET_TIMEOUT_MS = 1800000; // 30 minutes

	/** Maximum http connections per host (for REST calls only). */
	public int MAX_CONNECTIONS_PER_HOST = 15;

	/** Maximum total http connections (for REST calls only). */
	public int MAX_TOTAL_CONNECTIONS = 30;

	/** Whether to automatically follow HTTP redirects. */
	public boolean FOLLOW_REDIRECTS = true;
	
	private final String user;
	private final String passwd;
	
	public String getUser() {
		return user;
	}

	public String getPasswd() {
		return passwd;
	}

	public void setAuthScope(AuthScope authScope) {
		this.authScope = authScope;
	}

	public AuthScope getAuthScope() {
		return authScope;
	}

	public UsernamePasswordCredentials getCredentials() {
		return credentials;
	}

	private AuthScope authScope;

	private final UsernamePasswordCredentials credentials;

	private HttpParams params;

	public HttpParams getParams() {
		return params;
	}

	public void setParams(HttpParams params) {
		this.params = params;
	}

	private boolean sslActive;

	private SchemeRegistry schemeRegistry;
	
	public SchemeRegistry getSchemeRegistry() {
		return schemeRegistry;
	}

	public void setSchemeRegistry(SchemeRegistry schemeRegistry) {
		this.schemeRegistry = schemeRegistry;
	}

	/**
	 * Initializes HTTP parameters used by the connection manager
	 * Authorization parameters, configuration parameters
	 * @param baseURL base URL for the REST service
	 */
	public HttpCustomParameters(String baseURL) {
		
		String user = JFig.getInstance().getValue("serviceConfig", "user", "user");
		String password = JFig.getInstance().getValue("serviceConfig", "password", "pass");
		this.user = user != null ? user : "";
		this.passwd = password != null ? password : "";
		credentials = new UsernamePasswordCredentials(this.user, this.passwd);
		
		boolean sslActiv = JFig.getInstance().getBooleanValue("serviceConfig", "sslActive", "false");
		sslActive = sslActiv;
		
		//HTTP parameters configuration
		params = new BasicHttpParams();

		schemeRegistry = new SchemeRegistry();

		HttpConnectionParams.setConnectionTimeout(params, JFig.getInstance().getIntegerValue("serviceConfig", 
				"timeout", 
				String.valueOf(TIMEOUT_MS)));

		HttpConnectionParams.setSoTimeout(params, JFig.getInstance().getIntegerValue("serviceConfig", 
				"timeoutSocket", 
				String.valueOf(SOCKET_TIMEOUT_MS)));

		ConnManagerParams.setMaxTotalConnections(params, JFig.getInstance().getIntegerValue("serviceConfig", 
				"maxConnectionsHost", 
				String.valueOf(MAX_CONNECTIONS_PER_HOST)));
		
		//Register normal HTTP connections
		int port = JFig.getInstance().getIntegerValue("serviceConfig", "port", DEFAULT_PORT);
		if (port == 0) {
			try {
				port = Integer.parseInt(DEFAULT_PORT);
			}catch(NumberFormatException ex) {
				port = 8080;
			}
		}
			
		schemeRegistry.register(new Scheme(JFig.getInstance().getValue("serviceConfig", "protocol", DEFAULT_PROTOCOL),
				PlainSocketFactory.getSocketFactory(), 
				port));
		//Register HTTPS connections if enabled
		if (sslActive)
		{
			port = JFig.getInstance().getIntegerValue("serviceConfig", "securePort", DEFAULT_SSL_PORT);
			if (port == 0)
				port = 443;
			schemeRegistry.register(new Scheme(JFig.getInstance().getValue("serviceConfig", "secureProtocol", DEFAULT_SSL_PROTOCOL),
				SSLSocketFactory.getSocketFactory(), 
				port));
		}
		URL url;

		try {
			url = new URL(baseURL);
			authScope = new AuthScope(url.getHost(),
					AuthScope.ANY_PORT,
					AuthScope.ANY_REALM);
		}catch (MalformedURLException e){
			log.error("Error: ", e);
		}
	}
	/**
	 * Initializes HTTP parameters used by the connection manager
	 * Authorization parameters, configuration parameters
	 * @param user authorised used
	 * @param passwd password for authorised user
	 * @param baseURL base URL for the REST service
	 */
	public HttpCustomParameters(String user, String passwd, String baseURL) {
		this.user = user != null ? user : "";
		this.passwd = passwd != null ? passwd : "";
		credentials = new UsernamePasswordCredentials(this.user, this.passwd);
		
		boolean sslActiv = JFig.getInstance().getBooleanValue("serviceConfig", "sslActive", "false");
		sslActive = sslActiv;
		
		//HTTP parameterss configuration
		params = new BasicHttpParams();

		SchemeRegistry schemeRegistry = new SchemeRegistry();

		HttpConnectionParams.setConnectionTimeout(params, JFig.getInstance().getIntegerValue("serviceConfig", 
				"timeout", 
				String.valueOf(TIMEOUT_MS)));

		HttpConnectionParams.setSoTimeout(params, JFig.getInstance().getIntegerValue("serviceConfig", 
				"timeoutSocket", 
				String.valueOf(SOCKET_TIMEOUT_MS)));

		ConnManagerParams.setMaxTotalConnections(params, JFig.getInstance().getIntegerValue("serviceConfig", 
				"maxConnectionsHost", 
				String.valueOf(MAX_CONNECTIONS_PER_HOST)));
		
		//Register normal HTTP connections
		int port = JFig.getInstance().getIntegerValue("serviceConfig", "port", DEFAULT_PORT);
		if (port == 0) {
			try {
				port = Integer.parseInt(DEFAULT_PORT);
			}catch(NumberFormatException ex) {
				port = 8080;
			}
		}
			
		schemeRegistry.register(new Scheme(JFig.getInstance().getValue("serviceConfig", "protocol", DEFAULT_PROTOCOL),
				PlainSocketFactory.getSocketFactory(), 
				port));
		//Register HTTPS connections if enabled
		if (sslActive)
		{
			port = JFig.getInstance().getIntegerValue("serviceConfig", "securePort", DEFAULT_SSL_PORT);
			if (port == 0)
				port = 443;
			schemeRegistry.register(new Scheme(JFig.getInstance().getValue("serviceConfig", "secureProtocol", DEFAULT_SSL_PROTOCOL),
				SSLSocketFactory.getSocketFactory(), 
				port));
		}
		URL url;

		try {
			url = new URL(baseURL);
			authScope = new AuthScope(url.getHost(),
					AuthScope.ANY_PORT,
					AuthScope.ANY_REALM);
		}catch (MalformedURLException e){
			log.error("Error: ", e);
		}
	}
}
